#include "wifi.h"
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "nvs_flash.h"
#include "esp_system.h"
#include "esp_chip_info.h"
#include "esp_psram.h"
#include "esp_flash.h"
#include "esp_wifi.h"
#include "esp_log.h"
#include <netdb.h>

// /***********************************************************************SCAN*****************************************************************************/
// static const char *TAG = "scan";

// /**
//  * @brief 打印WiFi认证模式
//  * 
//  * @param authmode 认证模式枚举值
//  */
// static void print_auth_mode(wifi_auth_mode_t authmode) {
//     switch (authmode) {
//         case WIFI_AUTH_OPEN:
//             ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_OPEN");
//             break;
//         case WIFI_AUTH_WEP:
//             ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WEP");
//             break;
//         case WIFI_AUTH_WPA_PSK:
//             ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA_PSK");
//             break;
//         case WIFI_AUTH_WPA2_PSK:
//             ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA2_PSK");
//             break;
//         case WIFI_AUTH_WPA_WPA2_PSK:
//             ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA_WPA2_PSK");
//             break;
//         case WIFI_AUTH_WPA3_PSK:
//             ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA3_PSK");
//             break;
//         case WIFI_AUTH_WPA2_WPA3_PSK:
//             ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA2_WPA3_PSK");
//             break;
//         default:
//             ESP_LOGI(TAG, "Authmode \tUnknown");
//             break;
//     }
// }

// /**
//  * @brief 打印加密类型
//  * 
//  * @param pairwise_cipher 单播加密类型
//  * @param group_cipher 组播加密类型
//  */
// static void print_cipher_type(wifi_cipher_type_t pairwise_cipher, wifi_cipher_type_t group_cipher) {
//     switch (pairwise_cipher) {
//         case WIFI_CIPHER_TYPE_NONE:
//             ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_NONE");
//             break;
//         case WIFI_CIPHER_TYPE_WEP40:
//             ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_WEP40");
//             break;
//         case WIFI_CIPHER_TYPE_WEP104:
//             ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_WEP104");
//             break;
//         case WIFI_CIPHER_TYPE_TKIP:
//             ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_TKIP");
//             break;
//         case WIFI_CIPHER_TYPE_CCMP:
//             ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_CCMP");
//             break;
//         case WIFI_CIPHER_TYPE_TKIP_CCMP:
//             ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_TKIP_CCMP");
//             break;
//         default:
//             ESP_LOGI(TAG, "Pairwise Cipher \tUnknown");
//             break;
//     }
    
//     switch (group_cipher) {
//         case WIFI_CIPHER_TYPE_NONE:
//             ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_NONE");
//             break;
//         case WIFI_CIPHER_TYPE_WEP40:
//             ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_WEP40");
//             break;
//         case WIFI_CIPHER_TYPE_WEP104:
//             ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_WEP104");
//             break;
//         case WIFI_CIPHER_TYPE_TKIP:
//             ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_TKIP");
//             break;
//         case WIFI_CIPHER_TYPE_CCMP:
//             ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_CCMP");
//             break;
//         case WIFI_CIPHER_TYPE_TKIP_CCMP:
//             ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_TKIP_CCMP");
//             break;
//         default:
//             ESP_LOGI(TAG, "Group Cipher \tUnknown");
//             break;
//     }
// }


// void wifi_scan(void)
// {
//     // 初始化网络接口 - 这是TCP/IP协议栈的基础
//     ESP_ERROR_CHECK(esp_netif_init());

//     /* 创建默认的事件循环，用于处理WiFi等系统事件 */
//     ESP_ERROR_CHECK(esp_event_loop_create_default());

//     /* 创建并初始化STA模式的默认网络接口 */
//     esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
//     assert(sta_netif);  // 确保网络接口创建成功

//     /* WiFi初始化配置，使用默认参数 */
//     wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
//     ESP_ERROR_CHECK(esp_wifi_init(&cfg));

//     // 定义扫描参数
//     uint16_t number = DEFAULT_SCAN_LIST_SIZE;  // 最大扫描AP数量
//     wifi_ap_record_t ap_info[DEFAULT_SCAN_LIST_SIZE];  // 存储AP信息的数组
//     uint16_t ap_count = 0;  // 实际扫描到的AP数量

//     // 清空AP信息数组，避免脏数据
//     memset(ap_info, 0, sizeof(ap_info));

//     /* 设置WiFi为STA（工作站）模式 */
//     ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));

//     /* 启动WiFi功能 */
//     ESP_ERROR_CHECK(esp_wifi_start());

//     /* 开始扫描附近的WiFi网络
//     * 第一个参数：扫描配置（NULL表示使用默认配置）
//     * 第二个参数：是否阻塞（true=阻塞式扫描，等待扫描完成）
//     */
//     esp_wifi_scan_start(NULL, true);

//     /* 获取扫描到的AP列表记录 */
//     ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&number, ap_info));

//     /* 获取扫描到的AP数量 */
//     ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&ap_count));

//     // 打印扫描到的AP总数
//     ESP_LOGI(TAG, "Total APs scanned = %u", ap_count);

//     /* 遍历并打印每个WiFi网络的详细信息 */
//     for (int i = 0; (i < DEFAULT_SCAN_LIST_SIZE) && (i < ap_count); i++) {
//         ESP_LOGI(TAG, "SSID \t\t%s", ap_info[i].ssid);        // 网络名称
//         ESP_LOGI(TAG, "RSSI \t\t%d", ap_info[i].rssi);        // 信号强度
//         print_auth_mode(ap_info[i].authmode);                 // 认证模式
        
//         // 非WEP加密时显示加密类型
//         if (ap_info[i].authmode != WIFI_AUTH_WEP) {
//             print_cipher_type(ap_info[i].pairwise_cipher, ap_info[i].group_cipher);
//         }

//         ESP_LOGI(TAG, "Channel \t\t%d\n", ap_info[i].primary);  // 信道
//     }
// }
// /***********************************************************************STA*****************************************************************************/
// #include "freertos/event_groups.h"

// /* 链接wifi名称 */
// #define DEFAULT_SSID        "123"
// /* wifi密码 */
// #define DEFAULT_PWD         "aa1234567"
// /* 事件标志 */
// static EventGroupHandle_t   wifi_event;
// #define WIFI_CONNECTED_BIT  BIT0
// #define WIFI_FAIL_BIT       BIT1
// static const char *TAG1 = "static_ip";
// char lcd_buff[100] = {0};

// /* WIFI默认配置 */
// #define WIFICONFIG()   {                            
//     .sta = {                                        
//         .ssid = DEFAULT_SSID,                       
//         .password = DEFAULT_PWD,                    
//         .threshold.authmode = WIFI_AUTH_WPA2_PSK,   
//     },                                              
// }

// /**
//  * @brief       链接显示
//  * @param       flag:2->链接;1->链接失败;0->再链接中
//  * @retval      无
//  */
// void connet_display(uint8_t flag)
// {
//     if(flag == 2)
//     {
//         printf("连接成功\r\n");
//     }
//     else if (flag == 1)
//     {
//         printf("连接失败\r\n");
//     }
//     else
//     {
//         printf("连接重试\r\n");
//     }
// }

// /**
//  * @brief       WIFI链接糊掉函数
//  * @param       arg:传入网卡控制块
//  * @param       event_base:WIFI事件
//  * @param       event_id:事件ID
//  * @param       event_data:事件数据
//  * @retval      无
//  */
// static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
// {
//     static int s_retry_num = 0;

//     /* 扫描到要连接的WIFI事件 */
//     if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
//     {
//         connet_display(0);
//         esp_wifi_connect();
//     }
//     /* 连接WIFI事件 */
//     else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_CONNECTED)
//     {
//         connet_display(2);
//     }
//     /* 连接WIFI失败事件 */
//     else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
//     {
//         /* 尝试连接 */
//         if (s_retry_num < 20)
//         {
//             esp_wifi_connect();
//             s_retry_num++;
//             ESP_LOGI(TAG1, "retry to connect to the AP");
//         }
//         else
//         {
//             xEventGroupSetBits(wifi_event, WIFI_FAIL_BIT);
//         }

//         ESP_LOGI(TAG1,"connect to the AP fail");
//     }
//     /* 工作站从连接的AP获得IP */
//     else if(event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
//     {
//         ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
//         ESP_LOGI(TAG1, "static ip:" IPSTR, IP2STR(&event->ip_info.ip));
//         s_retry_num = 0;
//         xEventGroupSetBits(wifi_event, WIFI_CONNECTED_BIT);
//     }
// }

// /**
//  * @brief       WIFI初始化
//  * @param       无
//  * @retval      无
//  */
// void wifi_sta_init(void)
// {
//     static esp_netif_t *sta_netif = NULL;
//     wifi_event= xEventGroupCreate();    /* 创建一个事件标志组 */
//     /* 网卡初始化 */
//     ESP_ERROR_CHECK(esp_netif_init());
//     /* 创建新的事件循环 */
//     ESP_ERROR_CHECK(esp_event_loop_create_default());
//     sta_netif= esp_netif_create_default_wifi_sta();
//     assert(sta_netif);
//     wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
//     ESP_ERROR_CHECK( esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL) );
//     ESP_ERROR_CHECK( esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL) );
//     ESP_ERROR_CHECK(esp_wifi_init(&cfg));    
//     wifi_config_t  wifi_config = WIFICONFIG();
//     ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
//     ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
//     ESP_ERROR_CHECK(esp_wifi_start());

//     EventBits_t bits = xEventGroupWaitBits(wifi_event,
//             WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
//             pdFALSE,
//             pdFALSE,
//             portMAX_DELAY);

//     /* 判断连接事件 */
//     if (bits & WIFI_CONNECTED_BIT)
//     {
//         ESP_LOGI(TAG1, "connected to ap SSID:%s password:%s",
//                  DEFAULT_SSID, DEFAULT_PWD);
//     }
//     else if (bits & WIFI_FAIL_BIT)
//     {
//         connet_display(1);
//         ESP_LOGI(TAG1, "Failed to connect to SSID:%s, password:%s",
//                  DEFAULT_SSID, DEFAULT_PWD);
//     }
//     else
//     {
//         ESP_LOGE(TAG1, "UNEXPECTED EVENT");
//     }
//     vEventGroupDelete(wifi_event);
// }


static const char *TAG = "AP";
#define EXAMPLE_ESP_WIFI_SSID   "123"
#define EXAMPLE_ESP_WIFI_PASS   "123456789"
#define EXAMPLE_MAX_STA_CONN    5
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
static char lcd_buff[100] = {0};

static void wifi_event_handler(void *arg, esp_event_base_t event_base,
                               int32_t event_id, void *event_data)
{
    /* 设备连接 */
    if (event_id == WIFI_EVENT_AP_STACONNECTED)
    {
        wifi_event_ap_staconnected_t *event = (wifi_event_ap_staconnected_t *)event_data;
        ESP_LOGI(TAG, "station " MACSTR " join, AID=%d",
                 MAC2STR(event->mac), event->aid);
    } 
    /* 设备断开 */
    else if (event_id == WIFI_EVENT_AP_STADISCONNECTED)
    {
        wifi_event_ap_stadisconnected_t *event = (wifi_event_ap_stadisconnected_t *)event_data;
        ESP_LOGI(TAG, "station " MACSTR " leave, AID=%d",
                 MAC2STR(event->mac), event->aid);
    }
}

void wifi_init_softap(void)
{
    /* 初始化网卡 */
    ESP_ERROR_CHECK(esp_netif_init());

    /* 创建新的事件循环 */
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    /* 使用默认配置初始化包括netif的Wi-Fi */
    esp_netif_create_default_wifi_ap();
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL));
    /* 配置WIFI */
    wifi_config_t wifi_config = {
        .ap = {
            .ssid = EXAMPLE_ESP_WIFI_SSID,
            .ssid_len = strlen(EXAMPLE_ESP_WIFI_SSID),
            .password = EXAMPLE_ESP_WIFI_PASS,
            .max_connection = EXAMPLE_MAX_STA_CONN,
            .authmode = WIFI_AUTH_WPA_WPA2_PSK
            },
    };

    if (strlen(EXAMPLE_ESP_WIFI_PASS) == 0)
    {
        wifi_config.ap.authmode = WIFI_AUTH_OPEN;
    }

    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
    ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config));
    ESP_ERROR_CHECK(esp_wifi_start());

    esp_netif_ip_info_t ip_info;
    esp_netif_get_ip_info(esp_netif_get_handle_from_ifkey("WIFI_AP_DEF"), &ip_info);

    char ip_addr[16];
    inet_ntoa_r(ip_info.ip.addr, ip_addr, 16);
    ESP_LOGI(TAG, "Set up softAP with IP: %s", ip_addr);

    ESP_LOGI(TAG, "wifi_init_softap finished. SSID:'%s' password:'%s'",
             EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
    
}
